package com.oocl.scan.model;

import static com.oocl.scan.utils.ScanConstants.UNKNOWN;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.dom.*;

public class JavaClassElement {

    private String domainName;
    private String moduleName;
    private String className;
    private PackageDeclaration packageDeclaration;
    private String parent;
    private List imports;
    private List implementList;
    private TypeDeclaration typeDeclaration;
    private List<FieldDeclaration> fieldDeclarationList;
    private List<MethodDeclaration> methodDeclarationList;
    private HashMap<String, String> importMap;
    private HashMap<String, FieldElement> fieldMap;

    public HashMap<String, FieldElement> getFieldMap() {
        return fieldMap;
    }

    public void setImplementList(List implementList) {
        this.implementList = implementList;
    }

    public List getImplementList() {
        return implementList;
    }

    public PackageDeclaration getPackageDeclaration() {
        return packageDeclaration;
    }

    public void setPackageDeclaration(PackageDeclaration packageDeclaration) {
        this.packageDeclaration = packageDeclaration;
    }

    public String getDomainName() {
        return domainName;
    }

    public void setDomainName(String domainName) {
        this.domainName = domainName;
    }

    public String getModuleName() {
        return moduleName;
    }

    public void setModuleName(String moduleName) {
        this.moduleName = moduleName;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getParent() {
        return parent;
    }

    public void setParent(String parent) {
        this.parent = parent;
    }

    public List getImports() {
        return imports;
    }

    public void setImports(List imports) {
        this.imports = imports;
    }

    public TypeDeclaration getTypeDeclaration() {
        return typeDeclaration;
    }

    public void setTypeDeclaration(TypeDeclaration typeDeclaration) {
        this.typeDeclaration = typeDeclaration;
    }

    public List<FieldDeclaration> getFieldDeclarationList() {
        return fieldDeclarationList;
    }

    public void setFieldDeclarationList(List<FieldDeclaration> fieldDeclarationList) {
        this.fieldDeclarationList = fieldDeclarationList;
    }

    public List<MethodDeclaration> getMethodDeclarationList() {
        return methodDeclarationList;
    }

    public void setMethodDeclarationList(List<MethodDeclaration> methodDeclarationList) {
        this.methodDeclarationList = methodDeclarationList;
    }

    @Override
    public String toString() {
        return "JavaClassElement{" +
            "domainName='" + domainName + '\'' +
            ", moduleName='" + moduleName + '\'' +
            ", className='" + className + '\'' +
            ", packageDeclaration=" + packageDeclaration +
            ", parent='" + parent + '\'' +
            ", imports=" + imports +
            ", typeDeclaration=" + typeDeclaration +
            ", fieldDeclarationList=" + fieldDeclarationList +
            ", methodDeclarationList=" + methodDeclarationList +
            ", importMap=" + importMap +
            ", fieldMap=" + fieldMap +
            ", implementList=" + implementList +
            '}';
    }

    public void buildImportMap() {
        importMap = new HashMap<>();
        imports.forEach(obj->{
            ImportDeclaration importDeclaration = (ImportDeclaration) obj;
            String fullNam = importDeclaration.getName().getFullyQualifiedName();
            String[] packnames = fullNam.split("\\.");
            String className = packnames[packnames.length-1];
            importMap.put(className,fullNam);
        });
    }

    public void buildFieldMap() {
        fieldMap = new HashMap<>();
        fieldDeclarationList.forEach((fieldDeclaration -> {
            String fieldValue = "";
            if(!fieldDeclaration.getType().toString().equals("String")){
                return;
            }
            VariableDeclarationFragment variableDeclarationFragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0);
            if(variableDeclarationFragment.getInitializer() == null || !(variableDeclarationFragment.getInitializer() instanceof StringLiteral)){
                return;
            }
            fieldValue = variableDeclarationFragment.getInitializer().toString();
            FieldElement fieldElement = new FieldElement(this.getClassName(),((VariableDeclarationFragment)fieldDeclaration.fragments().get(0)).getName().getIdentifier(),
                    fieldDeclaration.getType().toString(), fieldValue);
            fieldMap.put(((VariableDeclarationFragment)fieldDeclaration.fragments().get(0)).getName().getIdentifier(), fieldElement);
        }));
    }

    public String findPackageNameByClass(String className) {
        if (importMap.containsKey(className)){
            return importMap.get(className);
        }
       return className;
    }

    public Object findClassNameByVariable(String variable,Map<String,Object> variableMap) {
        if (variableMap.containsKey(variable)){
            return variableMap.get(variable);
        }
        if (fieldMap.containsKey(variable)){
            return fieldMap.get(variable);
        }
        return UNKNOWN;
    }

    public String getJavaClassFullName(){
        return this.getPackageDeclaration().getName().toString() + "." + this.getClassName();
    }
}
